import re
import ipaddress
from .logger import get_logger

logger = get_logger()

def validate_args(args):  # 该方法用于验证输入参数是否合法
    if not _validate_target(args.target):
        raise ValueError("目标格式无效。必须是IP、IP范围或CIDR表示法")

    # 如果指定了端口，验证端口格式
    if args.ports and not _validate_ports(args.ports):
        raise ValueError("端口格式无效。必须是单个端口、逗号分隔列表或范围")

    # 验证线程数
    if args.threads < 1:
        raise ValueError("线程数必须为正数")

    # 验证超时时间
    if args.timeout < 1:
        raise ValueError("超时时间必须为正数")

    # 验证UDP重试次数
    if args.scan_type == 'udp' and args.udp_retries < 1:
        raise ValueError("UDP重试次数必须为正数")

    return True
def _validate_target(target):  # 该方法用于验证目标格式
    try:
        # 检查是否为有效的CIDR格式
        if '/' in target:
            ipaddress.ip_network(target)
            return True

        # 检查是否为IP范围格式
        if '-' in target:
            base = target.rsplit('.', 1)[0]
            start, end = target.rsplit('.', 1)[1].split('-')

            # 验证基础IP地址
            ipaddress.ip_address(f"{base}.{start}")

            # 验证范围值
            if not (start.isdigit() and end.isdigit()):
                return False
            if not (0 <= int(start) <= 255 and 0 <= int(end) <= 255):
                return False
            if int(start) > int(end):
                return False

            return True

        # 检查是否为单个IP地址
        ipaddress.ip_address(target)
        return True

    except ValueError:
        return False

def _validate_ports(ports):  # 该方法用于验证端口格式
    try:
        # 遍历所有端口配置(以逗号分隔)
        for part in ports.split(','):
            # 检查是否为端口范围
            if '-' in part:
                start, end = map(int, part.split('-'))
                # 验证端口范围是否有效(1-65535)
                if not (0 < start <= 65535 and 0 < end <= 65535):
                    return False
                # 确保起始端口小于结束端口
                if start > end:
                    return False
            else:
                # 验证单个端口是否有效
                port = int(part)
                if not 0 < port <= 65535:
                    return False
        return True
    except ValueError:
        return False